package com.jh.paymentchannel.service;

import cn.jh.common.utils.CommonConstants;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import cn.jh.common.utils.CommonsUtil;
import cn.jh.common.utils.TokenUtil;
import com.jh.paymentchannel.business.BankCard4AuthBusiness;
import com.jh.paymentchannel.pojo.BankCard4Auth;
import com.jh.paymentchannel.pojo.BankCardLocation;
import com.jh.paymentchannel.util.Util;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.springframework.util.StringUtils.trimAllWhitespace;
import static org.springframework.web.bind.ServletRequestUtils.getStringParameter;


@RestController
public class BankCard4AuthService {


    private static final Logger log = LoggerFactory.getLogger(BankCard4AuthService.class);

    private final BankCard4AuthBusiness bankCard4AuthBusiness;

    private final Util util;

    @Autowired
    public BankCard4AuthService(BankCard4AuthBusiness bankCard4AuthBusiness, Util util) {
        this.bankCard4AuthBusiness = bankCard4AuthBusiness;
        this.util = util;
    }

    /** 银行四要素验证 新接口 */
    @PostMapping(value = "/v1.0/paymentchannel/bankcard4/auth2")
    public Map<String, Object> verifyBankCard4(HttpServletRequest request) throws Exception {
        String realName = trimAllWhitespace(getStringParameter(request, "realName", ""));
        String idCard = trimAllWhitespace(getStringParameter(request, "idCard", ""));
        String bankCard = trimAllWhitespace(getStringParameter(request, "bankCard", ""));
        String mobile = trimAllWhitespace(getStringParameter(request, "mobile", ""));
        String btKey = trimAllWhitespace(getStringParameter(request, "bankTagKey", ""));
        String baKey = trimAllWhitespace(getStringParameter(request, "bankAuthKey", ""));
        String bankTagUrl = trimAllWhitespace(getStringParameter(request, "bankTagUrl", ""));
        String bankAuthUrl = trimAllWhitespace(getStringParameter(request, "bankAuthUrl", ""));

        realName = URLDecoder.decode(realName, UTF_8.displayName());

        Map<String, Object> result = new HashMap<>(2);
        BankCardLocation cardLocation = bankCard4AuthBusiness.findCardLocation(bankCard, btKey, bankTagUrl);

        BankCard4Auth bcAuth = bankCard4AuthBusiness.bankCard4Auth(mobile, bankCard, idCard, realName, baKey, bankAuthUrl);
        result.put("location", cardLocation);
        result.put("auth", bcAuth);
        return result;
    }

    /**
     * 银行四要素验证
     **/
    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/bankcard4/auth")
    public Object bandcard4Auth(
            @RequestParam(value = "realname") String realname,
            @RequestParam(value = "idcard") String idcard,
            @RequestParam(value = "bankcard") String bankcard,
            @RequestParam(value = "brandid") String brandid,
            @RequestParam(value = "mobile") String mobile) {
        try {
            realname = URLDecoder.decode(realname, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Map<String, Object> map = new HashMap<String, Object>();
        String jhKey = null;
        /*银行卡类型真伪验证*/
        try {
            String keyPlan = "bankTag";
            /*
             * 获取贴牌对应的key
             */
            RestTemplate restTemplates = new RestTemplate();
            URI uris = util.getServiceUrl("user", "error url request!");
            String urls = uris.toString() + "/v1.0/user/brand/query/jh/key?brand_id=" + brandid + "&keyPlan=" + keyPlan;
            String results = restTemplates.getForObject(urls, String.class);
            JSONObject jsonObject1 = JSONObject.fromObject(results);
            JSONObject res = jsonObject1.getJSONObject("result");
            jhKey = res.getString("jhKey");
        } catch (RestClientException e) {
            e.printStackTrace();
            log.info("聚合秘钥不正确");
        }

        map.put("location", bankCard4AuthBusiness.findCardLocation(bankcard, jhKey, CommonConstants.BANK_ASCRIPTION_URL));
        String jhKeys = null;

        /*银行卡四要素验证*/
        try {
            /*
             * 获取贴牌对应的key
             */
            String keyPlans = "bankAuth";
            RestTemplate restTemplate = new RestTemplate();
            URI uri = util.getServiceUrl("user", "error url request!");
            String url = uri.toString() + "/v1.0/user/brand/query/jh/key?brand_id=" + brandid + "&keyPlan=" + keyPlans;
            String result = restTemplate.getForObject(url, String.class);
            JSONObject jsonObject = JSONObject.fromObject(result);
            JSONObject resd = jsonObject.getJSONObject("result");
            jhKeys = resd.getString("jhKey");
        } catch (RestClientException e) {
            e.printStackTrace();
        }

        map.put("auth", bankCard4AuthBusiness.bankCard4Auth(mobile, bankcard, idcard, realname, jhKeys, CommonConstants.BANK_ASCRIPTION_URL));
        return map;
    }

    /**
     * 银行卡类型及真伪查询
     */
    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/bankcard/query/{token}")
    @ResponseBody
    public Object findBankCardInfo(HttpServletRequest request,
                                   @RequestParam("bankcard") String bankcard,
                                   @PathVariable("token") String token) {
        HashMap<Object, Object> map = new HashMap<>();
        if (bankcard == null || "".equals(bankcard)) {
            map.put(CommonConstants.RESP_CODE, CommonConstants.FALIED);
            map.put(CommonConstants.RESP_MESSAGE, "您输入的信息有误，请重新输入");
            return map;
        }
        long userId;
        long brandid;
        try {
            userId = TokenUtil.getUserId(token);
            brandid = TokenUtil.getBrandid(token);
        } catch (Exception e) {
            map.put(CommonConstants.RESP_CODE, CommonConstants.ERROR_TOKEN);
            map.put(CommonConstants.RESP_MESSAGE, "token无效");
            return map;
        }
        String keyPlan = "bankTag";
        /**
         * 获取贴牌对应的key
         */
        RestTemplate restTemplates = new RestTemplate();
        URI uris = util.getServiceUrl("user", "error url request!");
        String urls = uris.toString() + "/v1.0/user/brand/query/jh/key?brand_id=" + brandid + "&keyPlan=" + keyPlan;
        String results = restTemplates.getForObject(urls, String.class);
        JSONObject jsonObject1 = JSONObject.fromObject(results);
        JSONObject res = jsonObject1.getJSONObject("result");
        String jhKey = res.getString("jhKey");
        log.info("jhKey===============================" + jhKey);

        map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
        map.put(CommonConstants.RESULT, bankCard4AuthBusiness.findCardLocation(bankcard, jhKey, CommonConstants.BANK_ASCRIPTION_URL));
        map.put(CommonConstants.RESP_MESSAGE, "接口返回成功");
        return map;

    }

    /**
     * 所有银行卡四要素的分页查询
     */
    @RequestMapping(method = RequestMethod.GET, value = "/v1.0/paymentchannel/bankcard4/all")
    public Object allBankCard4s(HttpServletRequest request,
                         @RequestParam(value = "page", defaultValue = "0", required = false) int page,
                         @RequestParam(value = "size", defaultValue = "20", required = false) int size,
                         @RequestParam(value = "order", defaultValue = "DESC", required = false) Sort.Direction direction,
                         @RequestParam(value = "sort", defaultValue = "authTime", required = false) String sortProperty) {
        Pageable pageable = new PageRequest(page, size, new Sort(direction, sortProperty));
        Map map = new HashMap();
        map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
        map.put(CommonConstants.RESULT, bankCard4AuthBusiness.findAllBankCard4s(pageable));
        return map;
    }


    /**
     * 查询所有成功验证的分页
     */
    @RequestMapping(method = RequestMethod.GET, value = "/v1.0/paymentchannel/bankcard4/all_success")
    public Object allSuccessBankcard4s(HttpServletRequest request,
                                @RequestParam(value = "page", defaultValue = "0", required = false) int page,
                                @RequestParam(value = "size", defaultValue = "20", required = false) int size,
                                @RequestParam(value = "order", defaultValue = "DESC", required = false) Sort.Direction direction,
                                @RequestParam(value = "sort", defaultValue = "authTime", required = false) String sortProperty) {
        Pageable pageable = new PageRequest(page, size, new Sort(direction, sortProperty));

        Map map = new HashMap();
        map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
        map.put(CommonConstants.RESULT, bankCard4AuthBusiness.findAllSuccessBankCard4s(pageable));
        return map;
    }

    /**
     * 根据银行卡号
     */
    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/bankcard4/bankcard")
    public Object bankCard4ByBank(HttpServletRequest request,
                           @RequestParam(value = "bankcard") String bankcard) {

        Map map = new HashMap();
        map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
        map.put(CommonConstants.RESULT, bankCard4AuthBusiness.findBankCard4AuthByCard(bankcard));
        return map;
    }


    /**
     * 根据手机号码
     */
    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/bankcard4/mobile")
    public Object bankCard4ByMobile(@RequestParam(value = "mobile") String mobile) {
        Map map = new HashMap();
        map.put(CommonConstants.RESP_CODE, CommonConstants.SUCCESS);
        map.put(CommonConstants.RESULT, bankCard4AuthBusiness.findBankCard4AuthByMobile(mobile));
        return map;

    }


    /**
     * 根据卡号获取归属地
     */
    @RequestMapping(method = RequestMethod.POST, value = "/v1.0/paymentchannel/bankcard/location")
    public Object queryLocationByCard(@RequestParam(value = "cardid") String cardid,
                                      @RequestParam(value = "jhKey") String jhKey,
                                      @RequestParam(value = "jhUrl") String jhUrl) {
        try {
            Map map = new HashMap();
            BankCardLocation cardLocation = bankCard4AuthBusiness.findCardLocation(cardid, jhKey, jhUrl);
            map.put("bankCard4Auth", cardLocation);
            return map;
        }catch (Exception e){
            log.error("JuHeAPIBankCard4AuthService.queryLocationByCard，查询银行卡归属地异常========" + e.getMessage());
            return CommonsUtil.returnError("查询银行卡归属地失败！");
        }
    }

    /**
     * 根据卡号获取归属地
     * @param cardid
     * @param jhKey
     * @param jhUrl
     * @return
     */
    @PostMapping(value = "/v1.0/paymentchannel/bankcard/getBankLocation")
    public Object getBankLocation(@RequestParam(value = "cardid") String cardid,
                                  @RequestParam(value = "jhKey") String jhKey,
                                  @RequestParam(value = "jhUrl") String jhUrl) {
        try {
            BankCardLocation cardLocation = bankCard4AuthBusiness.findCardLocation(cardid, jhKey, jhUrl);
            if (null == cardLocation) {
                return CommonsUtil.returnError("未查询到该银行卡归属地信息！");
            }
            return CommonsUtil.returnSuccess("银行卡归属地信息查询成功！", cardLocation);
        } catch (Exception e) {
            log.error("JuHeAPIBankCard4AuthService.queryLocationByCard，查询银行卡归属地异常========" + e.getMessage());
            return CommonsUtil.returnError("查询银行卡归属地失败！");
        }
    }
}